package operador.equacoes;

import java.util.Random;

import base.EquacaoVelocidade;
import base.Particula;

public class EquacaoComC1C2Diferentes implements EquacaoVelocidade {

	private static double MAX_INERTIA = 0.9;
	private static double MIN_INERTIA = 0.4;
	
	private double MAX_C1_C2 = 2.5;
	private double MIN_C1_C2 = 1.5;
	
	private double fatorSubtracaoInercia = -1;
	private double fatorConstantes = -1;
	
	public void setTotalInteracoes(int totalInteracoes){
		fatorSubtracaoInercia = (MAX_INERTIA - MIN_INERTIA)/totalInteracoes;
		fatorConstantes = (MAX_C1_C2 - MIN_C1_C2)/totalInteracoes;
	}
	
	@Override
	public void calcularNovaPosicao(Particula particula, int interacao) {		
		double fatorInercia = MAX_INERTIA - interacao*fatorSubtracaoInercia;
		
		double c1 = MAX_C1_C2 - interacao*fatorConstantes;
		double c2 = MIN_C1_C2 + interacao*fatorConstantes;
		
		Random rand = new Random();
		
		double[] localBest = particula.getMelhorPosicaoParticula();
		double[] globalBest = particula.getMelhorPosicaoGlobalVizualizada();
		double[] posicaoAtual = particula.getPosicao();
		double[] posicaoNova = new double[posicaoAtual.length];
		double[] velocidadeAtual = particula.getVelocidade();
		double[] velocidadeNova = new double[velocidadeAtual.length];
		
		for(int i=0; i<posicaoAtual.length; i++){
			double novaVelocidade = fatorInercia * velocidadeAtual[i];
			novaVelocidade += c1 * rand.nextDouble()* (localBest[i] - posicaoAtual[i]);
			novaVelocidade += c2 * rand.nextDouble()* (globalBest[i] - posicaoAtual[i]);
			
			velocidadeNova[i] = novaVelocidade;
			posicaoNova[i] = posicaoAtual[i] + novaVelocidade;
		}
		
		particula.setVelocidade(velocidadeNova);
		particula.setPosicao(posicaoNova);
	}
}
